#include "StdAfx.h"
#include "vector3d.h"
#include <cmath>
#include <assert.h>

#define EPTHLON 1e-6

vector3d::vector3d(void)
{
	value[0] = 0.0f;
	value[1] = 0.0f;
	value[2] = 0.0f;
}

vector3d::vector3d(float x, float y, float z)
{
	value[0] = x;
	value[1] = y;
	value[2] = z;
}

vector3d::vector3d(float *const _value)
{
	value[0] = _value[0];
	value[1] = _value[1];
	value[2] = _value[2];
}

vector3d::vector3d(const vector3d& _value)
{
	value[0] = _value.x();
	value[1] = _value.y();
	value[2] = _value.z();
}

vector3d::~vector3d(void)
{
}

//getter
float vector3d::x() const
{
	return value[0];
}

float vector3d::y() const
{
	return value[1];
}

float vector3d::z() const
{
	return value[2];
}

const float* vector3d::xyz() const
{
	return value;
}

//setter
void vector3d::x(const float _value)
{
	value[0] = _value;
}

void vector3d::y(const float _value)
{
	value[1] = _value;
}

void vector3d::z(const float _value)
{
	value[2] = _value;
}

void vector3d::xyz(const float* _value)
{
	value[0] = _value[0];
	value[1] = _value[1];
	value[2] = _value[2];
}

void vector3d::xyz(const vector3d& _value)
{
	value[0] = _value.x();
	value[1] = _value.y();
	value[2] = _value.z();
}

//operator

vector3d vector3d::operator=(const vector3d& _value)
{
	value[0] = _value.x();
	value[1] = _value.y();
	value[2] = _value.z();
	return *this;
}

vector3d vector3d::operator-() const
{
	return vector3d(-value[0], -value[1], -value[2]);
}

vector3d vector3d::operator+(const vector3d& _value) const
{
	return vector3d(value[0] + _value.x(),
					value[1] + _value.y(),
					value[2] + _value.z());
}

vector3d vector3d::operator-(const vector3d& _value) const
{
	return vector3d(value[0] - _value.x(),
		value[1] - _value.y(),
		value[2] - _value.z());
}

vector3d vector3d::operator*(const vector3d& _value) const
{
	return vector3d(value[0] * _value.x(),
		value[1] * _value.y(),
		value[2] * _value.z());
}

vector3d vector3d::operator/(const vector3d& _value) const
{
	assert(_value.x()!=0 && _value.y()!=0 && _value.z()!=0 &&
		"vector3d error: div zero!");
	
	return vector3d(value[0] + _value.x(),
		value[1] + _value.y(),
		value[2] + _value.z());
}

float vector3d::len()
{
	return sqrt(value[0]*value[0] + value[1]*value[1] + value[2]*value[2]);
}

float vector3d::dot(const vector3d& _value) const
{
	return value[0]*_value.x() + value[1]*_value.y() + value[2]*_value.z();
}

vector3d vector3d::cross(const vector3d& _value) const
{
	return vector3d(value[1]*_value.z() - value[2]*_value.y(),
					value[2]*_value.x() - value[0]*_value.z(),
					value[0]*_value.y() - value[1]*_value.x());
}

void vector3d::normalize()
{
	float length = len();
	assert( (length*length > EPTHLON) 
		&& "vector3d error: trying to normalize a zero vector!");
	value[0]/=length;
	value[1]/=length;
	value[2]/=length;
}